package com.moonshineproject.plugin
{
	import com.moonshineproject.IDEModel;
	import com.moonshineproject.plugin.actionscript.as3parser.AS3ParserPlugin;
	import com.moonshineproject.plugin.actionscript.as3project.AS3ProjectPlugin;
	import com.moonshineproject.plugin.actionscript.fdb.FDBPlugin;
	import com.moonshineproject.plugin.actionscript.flashproject.FlashProjectPlugin;
	import com.moonshineproject.plugin.actionscript.mxmlc.MXMLCPlugin;
	import com.moonshineproject.plugin.actionscript.profiler.SWFProfilerPlugin;
	import com.moonshineproject.plugin.actionscript.swflauncher.SWFLauncherPlugin;
	import com.moonshineproject.plugin.console.ConsolePlugin;
	import com.moonshineproject.plugin.dragdrop.DragDropPlugin;
	import com.moonshineproject.plugin.filesearch.FileSearchPlugin;
	import com.moonshineproject.plugin.findreplace.FindReplacePlugin;
	import com.moonshineproject.plugin.fullscreen.FullscreenPlugin;
	import com.moonshineproject.plugin.globalerrorhandling.GlobalErrorHandlingPlugin;
	import com.moonshineproject.plugin.haxe.haxecompiler.HaxeCompilerPlugin;
	import com.moonshineproject.plugin.haxe.haxeproject.HaXeProjectPlugin;
	import com.moonshineproject.plugin.menu.MenuPlugin;
	import com.moonshineproject.plugin.menu.vo.MenuItem;
	import com.moonshineproject.plugin.project.ProjectPlugin;
	import com.moonshineproject.plugin.recentlyopened.RecentlyOpenedPlugin;
	import com.moonshineproject.plugin.selfprofiling.SelfProfilingPlugin;
	import com.moonshineproject.plugin.settings.SettingsPlugin;
	import com.moonshineproject.plugin.splashscreen.SplashScreenPlugin;
	import com.moonshineproject.plugin.svn.SVNPlugin;
	import com.moonshineproject.plugin.syntax.AS3SyntaxPlugin;
	import com.moonshineproject.plugin.syntax.CSSSyntaxPlugin;
	import com.moonshineproject.plugin.syntax.HTMLSyntaxPlugin;
	import com.moonshineproject.plugin.syntax.JSSyntaxPlugin;
	import com.moonshineproject.plugin.syntax.MXMLSyntaxPlugin;
	import com.moonshineproject.plugin.syntax.XMLSyntaxPlugin;
	import com.moonshineproject.plugin.syntax.PythonSyntaxPlugin;
	import com.moonshineproject.plugin.templating.TemplatingPlugin;
	import com.moonshineproject.plugin.update.UpdatePlugin;
	import com.moonshineproject.utils.moonshine_internal;

    use namespace moonshine_internal;

    public class PluginManager
    {
        // Core plugins
        private var corePlugins:Array = [
        	SettingsPlugin, 
			 ProjectPlugin,
			 TemplatingPlugin, 
			 DragDropPlugin, 
			 ConsolePlugin, 
			 GlobalErrorHandlingPlugin, 
			 SelfProfilingPlugin, 
			 FindReplacePlugin,
			 FullscreenPlugin,
			 RecentlyOpenedPlugin,
			 UpdatePlugin
		];

		// Plugins shipped with Moonshine
		private var defaultPlugins:Array = [
			MXMLCPlugin,
			AS3ProjectPlugin,
			AS3ParserPlugin,
			SWFLauncherPlugin,
			AS3SyntaxPlugin,
			CSSSyntaxPlugin,
			HTMLSyntaxPlugin,
			JSSyntaxPlugin,
			MXMLSyntaxPlugin,
			XMLSyntaxPlugin,
			PythonSyntaxPlugin,
			FDBPlugin,
			HaxeCompilerPlugin,
			HaXeProjectPlugin,
			SplashScreenPlugin,
			SVNPlugin,
			SWFProfilerPlugin,
			FlashProjectPlugin,
			FileSearchPlugin
		];


        private var model:IDEModel;

        private var registeredPlugins:Vector.<IPlugin> = new Vector.<IPlugin>();

        private var settingsPlugin:SettingsPlugin;

        private var menuPlugins:Array = [MenuPlugin];

        private var pendingPlugMenuItems:Vector.<MenuItem> = new Vector.<MenuItem>();

        public function PluginManager()
        {
            model = IDEModel.getInstance();
        }

        public function setupPlugins():void
        {
        	var allPlugins:Array = corePlugins.concat(defaultPlugins);
        	
            var plug:Class
            for each (plug in allPlugins)
            {
                var instance:IPlugin = new plug() as IPlugin;
                if (!instance)
                {
                    throw new Error("Can't add plugin that doesn't implement IPlugin.");
                }

                registerPlugin(instance);
            }           

			var menuInstance:MenuPlugin = new MenuPlugin();
			for each (var menuItem:MenuItem in pendingPlugMenuItems)
			{
				menuInstance.addPluginMenu(menuItem);
			}
			settingsPlugin.initializePlugin(menuInstance);
			
			registeredPlugins.push(menuInstance);
        }

        public function registerPlugin(plug:IPlugin):void
        {
            if (!plug)
                return;

            if (registeredPlugins.indexOf(plug) != -1)
            {
                throw Error("Plugin " + plug.name + " has already been registered");
                return;
            }
            registeredPlugins.push(plug);

            if (settingsPlugin) // nasty hack for now
            {
                settingsPlugin.initializePlugin(plug);
            }

            if (plug is IMenuPlugin)
            {
                var menu:MenuItem = IMenuPlugin(plug).getMenu();
                if (menu)
                    pendingPlugMenuItems.push(menu);
            }

            if (plug is SettingsPlugin)
            {
                SettingsPlugin(plug).pluginManager = this;
                settingsPlugin = SettingsPlugin(plug);
            }
        }

        moonshine_internal function getPluginByClassName(className:String):IPlugin
        {
            var plugins:Vector.<IPlugin> = getPlugins();
            var plug:IPlugin
            for each (plug in plugins)
            {
                if (String(plug).indexOf(className) != -1)
                {
                    return plug;
                }
            }
            return null;
        }

        moonshine_internal function getPlugins():Vector.<IPlugin>
        {
            return registeredPlugins;
        }


    }
}